之前在 Day14 示範過使用 Maplibre Style 新增兩個圖層,在前端呈現簡單的樣式。不過相信在前幾天的範例中,讀者應該也發現到屬性值可以不單純是數字或文字,而是包含在 JSON Array 內的各種表達式。
表達式的說明文件被紀錄在 expressions 一節。在 layers 的各個圖層中,被包含在 layout 和 paint 內的屬性值都適用表達式,用以更加靈活的適用不同狀況,例如:
表達式都是以 JSON Array 的型式存在,並在第一個元素賦予關鍵字。以下就來介紹幾個常用的表達式,並搭配實際範例:
可以使用 get, has, id 等關鍵字來取得或比較物件屬性,例如下面要決定圓圈顏色的表達式中:
{
"circle-color": [
"rgb",
// red is higher when feature.properties.temperature is higher
["get", "temperature"],
// green is always zero
0,
// blue is higher when feature.properties.temperature is lower
["-", 100, ["get", "temperature"]]
]
}
["get", "temperature"] 即代表取得物件 temperature 的屬性值,而 ["-", 100, ["get", "temperature"]] 則可以拆成兩部分來看:
["-", 100, X]: 100 - XX=["get", "temperature"]: X=temperature因此可以知道,其涵意是 100-溫度值。
而最外層由 rgb 開頭的 Array 也不難懂。雖然我們還沒學到該關鍵字,但後面接上三個表達式,很明顯就是要決定 RGB 值。所以上面範例中的圓圈值,一般來說就是 rgb(溫度,0,100-溫度) 的意思。(所以溫度為100時,顏色應該是暗紅色)
根據地圖的相機伸縮,Maplibre Style 會利用不同的 zoom 值來決定屬性。["zoom"] 這個表達式可以取得目前的縮放層級。
舉例來說,若我們需要依不同縮放層級調整圓圈大小,則可以使用:
{
"circle-radius": [
"interpolate", ["linear"], ["zoom"],
// zoom is 5 (or less) -> circle radius will be 1px
5, 1,
// zoom is 10 (or greater) -> circle radius will be 5px
10, 5
]
}
在使用關鍵字 interpolate 的情況下,圓圈半徑以設定的區間線性變化。從上面的設定來說,在 zoom=5 到 zoom=10 這個區間,其值會由 1px 線性變化到 5px,而超出區間的數值則保持不變。因此,我們可以用表格來表示半徑的變化:
| zoom | 半徑 |
|---|---|
| ... | 1 |
| 4 | 1 |
| 5 | 1 |
| 6 | 1.8 |
| 7 | 2.6 |
| 8 | 3.4 |
| 9 | 4.2 |
| 10 | 5 |
| 11 | 5 |
| 12 | 5 |
| ... | 5 |
渲染結果如下,可以看到隨著縮放層級的增加,紅色的圓圈也逐漸變大,非常符合直覺:
用不同關鍵字新增判斷邏輯,只要有點其它程式語言的概念,應該不難理解。例如,以下的關鍵字用於回傳布林值:
!
!=
<
<=
==
>
>=
舉例來說: ["<=", 1, 2] 會等同於 (1 <= 2),因此會回傳 false。
而條件式就有各種參數了。case表達式提供 if/then/else 的邏輯。而 match 則類似於其它語言中的 switch,可以為各種輸入值指定回傳值,並給定預設值。條件式可使用以下的關鍵字:
all所有參數都為 true 才會回傳 true,例如:["all", ["==", 1, 1], [">", 3, 1]] 會回傳 true
any任一參數為 true 就會回傳 true
case兩個參數為一組case,若前一個參數回傳 true 則回傳下一個參數。若所有組別都回傳 false,則使用預設值(最後一個參數)。例如:
["case",
["==" ["get", "gender"], "male"], "男生", <----一組case
["==" ["get", "gender"], "female"], "女生", <----一組case
"性別不明" <----預設值
]
會依物件的 gender 屬性來返回 男生, 女生, 性別不明等三個值。
match和 case 的差別在於,第一個參數是輸入值,用以和兩個一組的參數進行比對。因此上面的例子可以改寫為:
["match",
["get", "gender"], <----輸入值
"male", "男生", <----一組 match
"female", "女生", <----一組 match
"性別不明" <----預設值
]
其它還有 whthin(用於比對地圖上的相對位置) 和 coalesce 等條件式,不過先掌握上面幾個就很夠用了。
簡單來說,Maplibre Style Expression 就是要使用 JSON 格式來模擬常用程式語言中的函式和各種運算符號。因此許多想得到想不到的關鍵字都可以在說明頁面中找到。
例如數學符號的 abs, +, -, *, /、字串的操作 concat, downcase, upcase等。使用者沒必要全部記住,只要在需要使用時查閱文件即可,在此就不一一列舉。
表達式在使用上相當接近 lisp 的括號表達式,它們對 Style 中各種屬性的運算,也有點像 SASS 與 CSS 的關係。
透過表達式,製圖者可以為渲染結果做出更多精細控制,讓畫面上更加協調。也因此會需要向量圖磚中,各種物件的屬性來搭配才能發揮威力。所以在製作專門用途的地圖時, tile schema 和 Style 的設計會需要互相考量,依需求持續進行調整。